<?php
// +----------------------------------------------------------------------
// | 杭州十禾信息科技有限公司
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2015 http://www.shelpe.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: LeePuman <ysyzlsm@163.com>
// +----------------------------------------------------------------------

class CampaignModel extends NewzanModel{

	protected $tableName = 'campaigns';
    
	/* table columns */
    protected $fields = array(

    );		

	/* validations definitions */

    protected $_validate = array(
        
    );

    protected $_auto = array(

    );
    

    /** @var Model 删除掉的推广计划, 备份 */
    protected $_deletedMdl = null;
    /** @var Model */
    protected $_logMdl = null;
    /*
     * 创建一个新的推广计划
     */
	public function createCampaign($campaign_title){
    	$params = array(
    				'title' => $campaign_title,
    			);
     	$res = $this->_api->SimbaCampaignAddRequest($params);
     	$res = json_decode($res, true);
    	return $res['simba_campaign_add_response']['campaign'];
    	
    }
    
    /**
     * 得到一个推广计划可以投放的平台
     * @param int $user_id
     * @param int $campaign_id
     * @return 
     */
    
    public function getCampaignPlatform($user_id,$campaign_id){
    	$params = array(
    				'campaign_id' => $campaign_id
    			);
     	$res = $this->_api->SimbaCampaignPlatformGetRequest($params);
     	$res = json_decode($res, true);
    	return $res['campaign_platform'];
    	
    }

    public function getCountLikeTitle($title = '', $user_id)
    {
        $param = array(
                'title' => array(
                        'LIKE', "%$title%"
                    ),
                'user_id' => $user_id
            );
        return $this->field('title')->where($param)->select();
    }
    
    /**
     * 获取一个行业的系统默认分时折扣模板
     * @param int $cid
     * @param int $schedule_id ， 设定schedule id的时候可以读取特定ID的时间设置模板
     */
    
    public function getDefaultCampaignSchedule($cid , $schedule_id = 0){
    	if($schedule_id){
    		$whr = array(
    				'id' => $schedule_id 
    		);
    	}else{
    		$whr = array(
    				'cid' => $cid,
    				'user_id' => 0
    		);
    	}
    	$res = M('schedule_templates')->where( $whr )->find();
    	if($res){
    		return $res['template'];
    	}else{
    		return null;
    	}
    }
    
    
    /**
     * 设置一个推广计划的分时折扣
     * @param int $user_id,
     * @param int $campaign_id
     * @param string $schedule , 分时折扣的字符串
     * @return mixed 设置成功返回分时折扣的字符串，否则返回bool 
     */
    
    public function saveCampaignSchedule($user_id,$campaign_id , $schedule){
    	$params = array(
    				'campaign_id' => $campaign_id,
    				'schedule' => $schedule
    			);
    	$res = $this->_api->SimbaCampaignScheduleUpdateRequest($params);
    	$res = $res['campaign_schedule'];
    	
    	//save to local db
    	$whr = array(
    			'user_id' => $user_id,
    			'campaign_id'=> $campaign_id
    	);
    	$ret = $this->where($whr)->save( array('schedule' => $schedule) );
    	$setted_discount = explode(';' , $res->schedule);
    	$schedule_keys = array('一','二','三','四','五' ,'六' ,'日');
    	if( count($setted_discount) == 7 ){
    		// to get schedule settings of each day
    		$schedule = array_combine($schedule_keys, $setted_discount);
    	}else{
    		// it must be 'all' settings
    		$schedule = array();
    		foreach($schedule_keys as $weekday){
    			$schedule[$weekday] = '00:00-24:00:100';
    		}
    	}
    	
    	return $schedule;
    }
    
    public function getCampaignSchedule($user_id , $campaign_id){
    	$params = array(
    				'campaign_id' => $campaign_id
    			);
        $res = $this->where($params)->find();
    	$res = $res['schedule'];
		$setted_discount = explode(';' , $res);
		$schedule_keys = array('一','二','三','四','五' ,'六' ,'日');
		if( count($setted_discount) == 7 ){
			// to get schedule settings of each day
			$schedule = array_combine($schedule_keys, $setted_discount);
		}else{
			// it must be 'all' settings 
			$schedule = array();
			foreach($schedule_keys as $weekday){
				$schedule[$weekday] = '00:00-24:00:100';
			}
		}
    	
    	return $schedule;
    }

    public function getAreaOptions($depth = 1){
        $cachekey = "campaign_area_options_" . $depth;
        $resp = S($cachekey);
        $provinces = array();
        if(!$resp){
            $c = $this->_top_client;
            $result = $this->_api->SimbaCampaignAreaoptionsGetRequest();
            $short_names = array('西藏自治区', '宁夏回族自治区', '新疆维吾尔自治区');
            if($result){
                $result = object_to_array($result['area_options']->area_option);
                foreach ($result as $key => $city) {
                    if(($city['parent_id'] === 700 && ($city['level'] === 2 || $city['level'] === 3)) || $city['parent_id'] == 0) {
                        $city['name'] = trim($city['name']);
                        if(in_array($city['name'], $short_names)) {
                            $city['name'] = mb_substr($city['name'], 0, 2, 'utf-8');
                        }
                        if(strstr($city['name'], '省')) {
                            $city['name'] = mb_substr($city['name'], 0, -1, 'utf-8');
                        }
                        $provinces[$city['area_id']]['name'] = $city['name'];
                        unset($result[$key]);
                    }
                }
                foreach ($provinces as $city_id => $city) {
                    foreach ($result as $c) {
                        if($c['parent_id'] == $city_id) {
                            $provinces[$city_id]['cities'][$c['area_id']] = $c['name'];
                        }
                    }
                }
                S($cachekey, $provinces, 86400*30);
            }
        }else{
            $provinces = $resp;
        }
        return $provinces;
    }
    
    public function updateCampaignArea($user_id , $campaign_id , $area){
    	$params = array(
    				'campaign_id' => $campaign_id,
    				'area' => $area
    			);
    	$res = $this->_api->SimbaCampaignAreaUpdateRequest($params);
    	return $res['campaign_area'];
    }
    
    
    public function getCampaignArea($user_id , $campaign_id, $withOptions = false){
        $resp = $this->where(array('campaign_id' => $campaign_id))->find();
    	$areas_str = $resp["area"];

    	//$areas_str = 'all';
    	$selected_areas = $areas_str != 'all' ? explode("," , $areas_str) : 'all';
    	if($withOptions){
    		$areas_withoptions = array();
    		$area_options = $this->getAreaOptions(3);
    		foreach($area_options as $k => $a){
    			$selected = 0;
    			if( $selected_areas == 'all' || in_array($k, $selected_areas) ){
    				//如果省级在里面的话直接整个cities全部备选了
    				$selected = 2;
    			}
    			
				$areas_withoptions[$k] = array(
								'name' => $a['name'],
								'area_id' => $k,
								'selected' => $selected,
								'cities' => array()
							);
    				
				$selected_city_num = 0;
    			foreach( $area_options[$k]['cities'] as $city_id => $city_name){
    				if(!$selected){
    					$city_selected = in_array($city_id , $selected_areas) ? true : false;
    				}else{
    					$city_selected = true;
    				}
    				if($city_selected) {
    					++$selected_city_num;
    				}		
    				$areas_withoptions[$k]['cities'][$city_id] = array(
    													'name' => $city_name,
    													'area_id' => $city_id,
    													'selected' => $city_selected
    												);
    				// 根据城市选中状态更新省份选中状态.
    				if($selected_city_num == count($area_options[$k]['cities'])) {
    					$areas_withoptions[$k]['selected'] = 2;
    				} else if($selected_city_num > 0) {
    					$areas_withoptions[$k]['selected'] = 1;
    				}
    			}
    				 
    		}

    		return $areas_withoptions;
    		
    	}else{
    		return $selected_areas;
    	}
    }
    
    public function addCamapaign($user_id , $title , $nick = null){        
        // init a api request 
        
        import("@.Library.TaobaoAPI.taobaoAPI");
        $oauth = getUserAccessToken($user_id);
        $api = taobaoAPI::init($oauth["access_token"]);   
        $campaign = $api->addCampaign($title , $nick);
        
        if($campaign) {
	        //add this campaign to local storage 
	        $data = array(
	            'campaign_id' => $campaign->campaign_id,
	            'user_id' => $user_id,
	            'title' => $campaign->title,
	            'nick' => $campaign->nick,
	            'create_time' => $campaign->create_time,
	            'modified_time' =>$campaign->last_update_time,
	            'updated_time' => date("Y-m-d H:i:s")
	        );
	        $result = $this->add($data , array() , true);

	        // 记录log
	        $this->addLog($campaign->campaign_id, CampaignLogActions::ADD,
	        		0, json_encode($campaign));
	        
	        return $campaign->campaign_id;
        } else {
        	return false;
        }
    }
    
    public function getCampaignBudget($user_id , $campaign_id){
        $res = $this->_api->SimbaCampaignBudgetGetRequest( array("campaign_id" => $campaign_id) );
        $budget = (array) $res["campaign_budget"];
        
        $existentCampaign = $this->getCampaignById($user_id, $campaign_id, false);
        $existentCampaign = isset($existentCampaign['campaign']) ? $existentCampaign['campaign'] : null;
        if($existentCampaign && $budget["budget"] != $existentCampaign["budget"]) {
        	$this->where( array( "campaign_id" => $campaign_id , "user_id" => $user_id) )->save( array( 
        			"budget" => $budget["budget"],
        			"updated_time" => date("Y-m-d H:i:s")
        	) );
        	$this->addLog($campaign_id, CampaignLogActions::UPDATE_BUDGET, $budget["budget"]);
        }
        return $budget["budget"];
    }
    
    public function updateCampaignPlatform( $user_id , $campaign_id , $platform){
    	/* if no changes then do nothing */
    	$whr = array( 'campaign_id' => $campaign_id  , "user_id" => $user_id );
    	$res = $this->where($whr)->find();
    	if(!$res) {
    		return false;
    	}
		$platform['campaign_id'] = $campaign_id;
    	$ret = $this->_api->SimbaCampaignPlatformUpdateRequest($platform);
		$ret = json_decode( json_encode($ret) , true );
		$platform = $ret['campaign_platform'];
    	//add log first
    	$this->addLog($campaign_id, CampaignLogActions::UPDATE_PLATFORM, 1 , json_encode( array('old' => $res['platform'] , 'new' => $platform) ) );
    	$data = array(
    				'platform' => json_encode($platform)
    			);
    	//无异常的话就开始更新数据库了
    	$this->where($whr)->save($data);
    	return $platform;
    }
    
    public function updateCampaignStatus( $user_id , $campaign_id , $status){
    	/* if no changes then do nothing */
    	
    	$whr = array( 'campaign_id' => $campaign_id  , "user_id" => $user_id );
    	$res = $this->where($whr)->find();
    	if(!$res) {
    		return false;
    	}   
    	
    	if( $res['online_status'] == $status['online_status'] && $res['title'] == $status['title'] ){
    		return $res;
    	}
    	
    	$ret = $this->_api->SimbaCampaignUpdateRequest($status); 	
    	
    	//无异常的话就开始更新数据库了
    	$campaign = (array) $ret['campaign'];
    	$this->where($whr)->save($campaign);
    	return $campaign;
    }
    
    public function getCampaignCats($campaign_id , $top = true){
    	$cids = M('adgroups')->where( array('campaign_id' => $campaign_id) )->getField('category_ids' , true);
    	$user_cids = array();
    	foreach($cids as $c){
    		$tmp = explode(' ',$c);
    		if($top){
    			$user_cids[] = $tmp[0];
    		}else{
    			$user_cids[] = array_pop( $tmp ) ;
    		}
    
    	}
    	$user_cids = array_count_values($user_cids);
    	asort($user_cids);
    	return $user_cids;
    }
     
    public function updateCampaignBudget($user_id , $campaign_id , $budget , $use_smooth = "true"){
    
        /* if no changes then do nothing */
        
        $whr = array( 'campaign_id' => $campaign_id  , "user_id" => $user_id );
        $res = $this->where($whr)->find();
        if(!$res) {
        	return false;
        }
        
        if($res["budget"] == $budget){
            return $res["campaign_id"];
        }
        $data = array(
            'campaign_id' => $campaign_id,
            'budget' => $budget,
            'use_smooth' => $use_smooth
        );
        $result= $this->_api->SimbaCampaignBudgetUpdateRequest($data);
        
        $retBudget = (array) $result['campaign_budget'];
        if($retBudget) {
	        //update local storage;
	        $this->where( array( 'campaign_id' => $campaign_id ) )->save( array("budget" => $budget , "use_smooth" => (bool) $use_smooth) );
	        
	        // add log
	        $this->addLog($campaign_id, CampaignLogActions::UPDATE_BUDGET,
	        		$budget, $retBudget);
	        
	        return $campaign_id;
        } else {
        	return false;
        }
    }
     
       
    public function getCampaignInfo($user_id, $campaign_id){
        return $this->where( array("user_id" => $user_id, "campaign_id" => $campaign_id) )->find();
    }

    public function getCampaignById($user_id, $campaign_id , $withSummary=false){
        $whr = array(
            'user_id' => $user_id,
            'campaign_id' => $campaign_id
            );
        $campaign = $this->where($whr)->find();
        if(!$campaign) return false;
            $c = array();

        //if with summary 
        $summary = null;
        if($withSummary){
            $rptMdl = new RptCampaignModel();
            $summary = $rptMdl->getAllCampaignsStat($campaign_id);        	
        }
        $data = array(
            'campaign' => $campaign,
            'summary' =>$summary
        );
        return $data;
    }
     
   
    public function getCampaigns($user_id , $with_summary = false , $from = null , $to = null)
    {
        $campaigns = $this->where( array( "user_id" => $user_id ) )->select( array( "assoc_key" => true) );

        if($with_summary)
        	throw_exception('不再支持在此方法内获取Summary信息. 现需使用RptCampaignModel::getAllCampaignsStat()单独获取.');
        return $campaigns;
    }

     
     public function removeCampaign($userId, $campaignId) {
     	$existentCampaign = $this->where(array('campaign_id' => $campaignId, 'user_id'=>$userId))->find();
     	$res = $this->where(array('campaign_id' => $campaignId, 'user_id'=>$userId))->delete();
     	if($res) {
     		$this->_getDeletedMdl()->add($existentCampaign);
     		$this->addLog($campaignId, CampaignLogActions::DEL);
     	}
     	return $res;	
     }
     
     /**
      * 添加一条log记录.
      *
      * @see CampaignLogActions
      * @param int $campaignId
      * @param int $action 使用CampaignLogActions::XX常量. 示例: CampaignLogActions::ADD
      * @param int $newVal 新的整型值
      * @param string $note 字符串备注. 例如可以给定为关键词修改后的状态json: {max_price: NNN, match_scope: NNN, qscore: NNN}
      * @return false|int ThinkkPHP添加记录的返回值. 失败返回false, 否则返回key.
      */
     public function addLog($campaignId, $action, $newVal = 0, $note = '') {
     	$res = $this->_getLogMdl()->add(array(
     			'campaign_id' => $campaignId,
     			'action' => $action,
     			'new_int_val' => $newVal,
     			'note' => $note,
     	));
     	return $res;
     }
     

      /**
       * 解释一条adgrouop log 的note记录
       * @param 一条adgroup的log记录
       * @return mixed 
       * @see parent::getLogs
       * 
       */
      public function readLog($log, $simple_disp){
      	$detailed_log = parent::readLog($log, $simple_disp);
        //修正CampaignActionLog的数字问题，其他log类小于10的都是自动操作，大于10的才是手动操作
        //TODO 修正到统一的形式
      	$detailed_log['action_type'] = 'manual';
      	//解释note记录
      	$note = $detailed_log['action_note'];
      	$ad_disp = $simple_disp ? '' : '[ID: ' . $log['campaign_id'] . ']';
      	$action_note = '';
      	switch($log['action']) {
      		case CampaignLogActions::ADD:
      			$action_note = "添加推广计划";
      			break;
      		case CampaignLogActions::DEL:
      			$action_note = "删除推广计划";
      			break;
            case CampaignLogActions::UPDATE_BUDGET:
      			$action_note = "修改推广计划日限额为￥" . $log['new_int_val'];
      			break;
            case CampaignLogActions::UPDATE_AREA:
                $action_note = "修改推广地域";
                break;

            case CampaignLogActions::UPDATE_ONLINE_STATUS:
                $extra_note = json_decode ( $log['note'] , true) ;
                $action_note = $extra_note['settle_status'] == 'online' ? '开启推广计划' : '关闭推广计划';
                break;

            case CampaignLogActions::UPDATE_PLATFORM:
                $action_note = '修改推广计划投放平台';
                break;

            case CampaignLogActions::UPDATE_TITLE:
                $extra_note = json_decode ( $log['note'] , true) ;
                $action_note = '修改推广计划标题 : ' . $extra_note['old']['title'] . ' -> ' . $extra_note['new']['title'];
                break;

      	}
      	$detailed_log['action_note'] = $action_note;

      	return $detailed_log;
      }
     /**
      * @return Model
      */
     protected function _getDeletedMdl() {
     	if($this->_deletedMdl == null) {
     		$this->_deletedMdl = M('campaigns_deleted');
     	}
     	return $this->_deletedMdl;
     }

     /**
      * @return Model
      */
     protected function _getLogMdl() {
     	if($this->_logMdl == null) {
     		$this->_logMdl = M('campaigns_log');
     	}
     	return $this->_logMdl;
     }
     
     
}


/**
 * 推广计划操作类型常量
 *
 * @author weiping
 */
class CampaignLogActions {
	/** 添加 */
	const ADD = 0;
	/** 删除 */
	const DEL = 1;
	/** 更新预算 */
	const UPDATE_BUDGET = 2;
	/**更新上下线状态 **/
	const UPDATE_ONLINE_STATUS = 3;
	/**更新推广计划标题**/
	const UPDATE_TITLE = 4;
	/**更新推广地域**/
	const UPDATE_AREA = 5;
	/**更新投放平台**/
	const UPDATE_PLATFORM = 6;
}
